package com.ruge.spring.cloud.gateway.filter;

import com.ruge.spring.cloud.gateway.base.exception.BaseBusinessException;
import com.ruge.spring.cloud.gateway.base.response.Response;
import com.ruge.spring.cloud.gateway.base.token.CheckTokenResponse;
import com.ruge.spring.cloud.gateway.base.token.Token;
import com.ruge.spring.cloud.gateway.base.token.TokenCheckAPIs;
import com.ruge.spring.cloud.gateway.error.ApiGatewayError;
import com.ruge.spring.cloud.gateway.util.JsonTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * @author 嘿丷如歌
 * @version V1.0
 * @Description: UserTokenChecker
 * @date 2021/4/26 22:29
 */
@Slf4j
@Component
public class UserTokenChecker {
    private final Base64.Encoder base64 = Base64.getEncoder();

    @Resource
    private TokenCheckAPIs tokenCheckAPIs;

    void check(String token) {
        try {
            // 调用tokenCheck服务检查token
            CheckTokenResponse response = tokenCheckAPIs.checkToken(token);
            if (response.getStatus() == Response.Status.SUCCEED) {
                appendRouteHeader(response, token);
            } else {
                log.info("checkUserToken req faild[errorCode={}, errorMsg={}].", response.getErrorCode(), response.getErrorMessage());
                throw new BaseBusinessException(ApiGatewayError.TOKEN_AUTH_FAILED);
            }
        } catch (Throwable e) {
            if (e instanceof BaseBusinessException) {
                throw (BaseBusinessException) e;
            } else {
                log.error("UserToken checker Unknow Error.", e);
                BaseBusinessException ex = new BaseBusinessException(ApiGatewayError.UNKNOWN_TOKEN_ERROR);
                throw ex;
            }
        }
    }

    private void appendRouteHeader(CheckTokenResponse response, String requestToken) throws UnsupportedEncodingException {
        Token token = response.getToken();
        // 设置token对象到header中
        // 此处代码为了兼容mosc和tsf，尚未明确mosc为什么要这么些，暂时保留原来的代码
        String tokenStr = base64.encodeToString(JsonTool.getBeanToJson(token).getBytes(StandardCharsets.UTF_8));
        // 打印日志
        log.debug("checkUserToken req success.");
        log.debug("*****************************");
        log.debug("token:{}", tokenStr);
        log.debug("*****************************");
    }

    String getRequestToken(ServerHttpRequest request) {
        String requestToken = request.getQueryParams().getFirst("token");
        //为空时取radio、music token
        if (StringUtils.isBlank(requestToken)) {
            requestToken = request.getHeaders().getFirst("Authorization");
        }

        //为空时取appstore token
        if (StringUtils.isBlank(requestToken)) {
            requestToken = request.getHeaders().getFirst("accessToken");
        }
        return requestToken;
    }
}
